iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 14
0
自我挑戰組

從 RedHat OpenShift 社群版 OKD 看 Kubernetes系列 第 14

[偷一下未來進度]Day 14 :Kubernetes 純手動部署與設定 EFK (4/4)

  • 分享至 

  • xImage
  •  

嗨各位今天過得好嗎?是不是有將Bug成功解出呢?還是當成技術債以後再來償還啊xD
昨天已經部署好 Elasticsearch 叢集,該叢集包含了三台 Master Node 以及三個 Worker Node ,今天我要接續著部署 EFK 服務中的 K-ibana 與 F-luentd ,比起 Elasticsearch 這種有狀態的叢集 Kibana 與 Fluentd 已部署的角度來說相對的簡單。

Kibana

Kibana 提供一個資料視覺化的操作平台。使用者能夠透過 Kibana 快速的將 Elasticsearch 中所查詢到的資料生成圖表、表格、地圖以較為圖像式的方式呈現。

Kibana 的部署與安裝相當的簡單,這邊可以參考Kubernetes Github 中 Addons 的 yaml 設定,我也是直接從那邊改過來的,對環境若有其他要求可以依照自身需求進行更改。

部署

apiVersion: apps/v1
kind: Deployment
metadata:
  name: kibana
  namespace: log
  labels:
    app: kibana
spec:
  replicas: 1
  selector:
    matchLabels:
      app: kibana
  template:
    metadata:
      labels:
        app: kibana
    spec:
      containers:
      - name: kibana
        image: docker.elastic.co/kibana/kibana-oss:6.4.3
        env:
          - name: ELASTICSEARCH_HOSTS
            value: http://elasticsearch-data.log.svc.cluster.local:9200
          - name: SERVER_NAME
            value: kibana
        ports:
        - containerPort: 5601
          name: dashboard
          protocol: TCP
        livenessProbe:
          httpGet:
            path: /api/status
            port: ui
          initialDelaySeconds: 5
          timeoutSeconds: 10
        readinessProbe:
          httpGet:
            path: /api/status
            port: ui
          initialDelaySeconds: 5
          timeoutSeconds: 10
---
kind: Service
apiVersion: v1
metadata:
  labels:
    app: kibana
  name: kibana
  namespace: log
spec:
  ports:
    - port: 5601
      targetPort: 5601
  selector:
    app: kibana
  type: NodePort

部署完成後我們可以透過 kubectl 指令去檢查部署狀態,檢查是否 kibana Pod 與 Service有正確的建立完成。

$kubectl get pod,svc -n log


NAME                                          READY   STATUS             RESTARTS   AGE
pod/kibana-dfd49f7df-rrs8s                   1/1     Running   0          29s


NAME                              TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
service/kibana                    NodePort    10.233.57.34    <none>        5601:32643/TCP   6m48s

如果看到 Kibana Pod 已經處於 Running 的狀態代表已經部署成功,我們可以透過剛剛建立的NodePort 存取這個服務,只要在瀏覽器中 url 的位置輸入http://:,即可看到 Kibina 的 Dashboard 畫面。

現在看到 Kibana 的 Dashboard 畫面應該是沒有任何 Elasticsearch 的資料,這是正常的因為我們還沒有建立 Fluentd 來將資料塞入 Elasticsearch 裡面,所以下面我們就來建立 Fluentd ,透過 Fluentd 傳遞一下簡單的資料吧~

Fluentd

Fluentd 是一個 Log 訊息收集的工具。支援各種不同的資料來源如:Application Logs 、 Network Protocols 、 IOT Devices Logs 等等,並有豐富的 Plugins 可以對資料進行過濾、分析、統一格式一系列的操作,最後可以將資料輸出到各式各樣的後端儲存平台上如 AWS S3 、 MySQL 、 Hadoop DFS 等儲存平台。

工作原理大概就如同下面這張圖所表示的,我們看左下角的 Kubernetes Cluster 就好不用管 AWS , Pod 裡面會有輕量級的 fluentbit ( fluentd 的一種但因為少很多套件所以他更輕量),他會將我們的 Log 資料打到一個 fluentd 身上,這個 fluentd 會決定這個 Log 資料要怎麼走,可以送到 Elasticsearch 上也可以存到 Amazon S3 (這邊的選擇可以很多元、此圖只列出部分,有興趣的朋友可以到 fluentd List of Data Outputs 去查查呦!)。


(圖片參考來源:Building an Open Data Platform: Logging with Fluentd and Elasticsearch)

部署

這邊我們可以參考 fluentd official github,這裡面有描述如何安裝一個 Fluentd 到 Kubernetes 上,我這邊做一個簡化版部署的 yaml 檔。(小心服用,我簡化很多東西:"P)

apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  name: fluentd
  namespace: kube-system
  labels:
    k8s-app: fluentd-logging
    version: v1
spec:
  template:
    metadata:
      labels:
        k8s-app: fluentd-logging
        version: v1
    spec:
      tolerations:
      - key: node-role.kubernetes.io/master
        effect: NoSchedule
      containers:
      - name: fluentd
        image: gcr.io/google-containers/fluentd-elasticsearch@sha256:5a704c386f66bb3c24e3bcf2e94269c426f1473100fcd37b31579ca8b709c558
        env:
          - name: FLUENTD_ARGS
            value: --no-supervisor -q
        resources:
          limits:
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 200Mi
        volumeMounts:
        - name: varlog
          mountPath: /var/log
        - name: varlibdockercontainers
          mountPath: /var/lib/docker/containers
          readOnly: true
        - name: config-volume
          mountPath: /etc/fluent/config.d
      terminationGracePeriodSeconds: 30
      volumes:
      - name: varlog
        hostPath:
          path: /var/log
      - name: varlibdockercontainers
        hostPath:
          path: /var/lib/docker/containers
      - name: config-volume
        configMap:
          name: fluentd-es-config-v0.2.0
---
kind: ConfigMap
apiVersion: v1
metadata:
  name: fluentd-es-config-v0.2.0
  namespace: kube-system
data:
  system.conf: |-
    <system>
      root_dir /tmp/fluentd-buffers/
    </system>

  containers.input.conf: |-
    <source>
      @id fluentd-containers.log
      @type tail
      path /var/log/containers/*.log
      pos_file /var/log/es-containers.log.pos
      tag raw.kubernetes.*
      read_from_head true
      <parse>
        @type multi_format
        <pattern>
          format json
          time_key time
          time_format %Y-%m-%dT%H:%M:%S.%NZ
        </pattern>
        <pattern>
          format /^(?<time>.+) (?<stream>stdout|stderr) [^ ]* (?<log>.*)$/
          time_format %Y-%m-%dT%H:%M:%S.%N%:z
        </pattern>
      </parse>
    </source>

    # Detect exceptions in the log output and forward them as one log entry.
    <match raw.kubernetes.**>
      @id raw.kubernetes
      @type detect_exceptions
      remove_tag_prefix raw
      message log
      stream stream
      multiline_flush_interval 5
      max_bytes 500000
      max_lines 1000
    </match>
    # Concatenate multi-line logs
    <filter **>
      @id filter_concat
      @type concat
      key message
      multiline_end_regexp /\n$/
      separator ""
    </filter>
 # Fixes json fields in Elasticsearch
    <filter kubernetes.**>
      @id filter_parser
      @type parser
      key_name log
      reserve_data true
      remove_key_name_field true
      <parse>
        @type multi_format
        <pattern>
          format json
        </pattern>
        <pattern>
          format none
        </pattern>
      </parse>
    </filter>
  output.conf: |-
    <match **>
      @id elasticsearch
      @type elasticsearch
      @log_level info
      type_name _doc
      include_tag_key true
      host elasticsearch-discovery.log.svc.cluster.local
      port 9200
      logstash_format true
      request_timeout 15s
      <buffer>
        @type file
        path /var/log/fluentd-buffers/kubernetes.system.buffer
        flush_mode interval
        retry_type exponential_backoff
        flush_thread_count 2
        flush_interval 5s
        retry_forever
        retry_max_interval 30
        chunk_limit_size 2M
        queue_limit_length 8
        overflow_action block
      </buffer>
    </match>

除了 fluentd 的 Deployment 之外,我們還要針對fluentd 的 input rule 、out rule 以及filter 進行設定,這邊採用 configMap 的方式設定這些 rule 。 fluentd Pod 啟動時會載入 configmap 並使用。

這邊簡單的說明一下我將 Host 上的 /var/lib/docker/containers 位置掛載到 fluentd 中的 /var/log/containers 位置上,在configmap 我們有設定 fluentd 的 input rule 將 /var/log/containers/*.log 作為輸入端,經過幾個 以及 filter rule 處理後送出到 output rule , 在 output rule 這邊 host 的位置是 elasticsearch-discovery.log.svc.cluster.local 也就是將資料送到 elasticsearch 上。

檢查一下

可以透過 kubectl 指令檢查當前的 EFK 環境部署狀況,如果全部都跑起來的話就沒問題拉~

$kubectl get pod,svc -n log
NAME                                          READY   STATUS             RESTARTS   AGE
pod/elasticsearch-master-65c699ddfd-fsrc5     1/1     Running   0          26h
pod/elasticsearch-master-65c699ddfd-lhfff     1/1     Running   0          26h
pod/elasticsearch-master-65c699ddfd-qx8j6     1/1     Running   0          26h
pod/elasticsearch-data-0                      1/1     Running   0          26h
pod/elasticsearch-data-1                      1/1     Running   0          26h
pod/elasticsearch-data-2                      1/1     Running   0          26h
pod/kibana-dfd49f7df-rrs8s                    1/1     Running   0          2h


NAME                              TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
service/kibana                    NodePort    10.233.57.34    <none>        5601:32643/TCP   2h
service/elasticsearch-discovery   ClusterIP   10.233.41.249   <none>        9300/TCP,9200/TCP   26h

接著我們可以去看 Kibana 的 Dashboard 目前應該會有資料傳進來,我們可以直接查詢 Pod/Container 相關的訊息。


Kibina 有收到 elasticsearch 的資料 Dashboard 畫面呈現

接著我們可以設定資料的 index pattern , 這邊就選全部就好也就是用 * 來吃全部, time Filter 用 @timestamp 然後就可以建立我們的 index pattern囉。


目前收到的資料,為這些資料建立 index pattern


time Filter 用 @timestamp

我們的 Kubernetes Cluster 的 Container 資料就被收進 EFK 系統囉,可以從下面這張圖看到...已經收了滿多資料進系統了。

Kibina 顯示 index pattern 的資料畫面

小結

今天我們部署完整個 EFK Log 收集系統其中包含三個開源專案分別是 Elasticsearch 、 Fluentd 和 Kibana ,部署時經歷了一些波折不過也是順利的跑了起來。不知道大家有沒有發現部署 Elasticsearch 的時候覺得非常煩躁,擴展節點的時候去算他的 minimum_master_nodes ,有沒有什麼工具能幫我們簡化這些部署活及與流程呢?明天將為各位揭曉。


上一篇
[偷一下未來進度]Day 13 :Kubernetes 純手動部署與設定 EFK (3/4)
下一篇
[偷一下未來進度]Day 15 :Kubernets有狀態應用的管理
系列文
從 RedHat OpenShift 社群版 OKD 看 Kubernetes17
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言